package com.itgacl.magic4j.libcommon.component.storage;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import com.itgacl.magic4j.libcommon.component.cache.CacheService;
import com.itgacl.magic4j.libcommon.component.storage.enums.StorageTypeEnum;
import com.itgacl.magic4j.libcommon.component.storage.service.StorageService;
import com.itgacl.magic4j.libcommon.component.storage.service.impl.*;
import com.itgacl.magic4j.libcommon.constant.Constants;
import com.itgacl.magic4j.libcommon.util.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import javax.sql.DataSource;
import java.util.Properties;

@Slf4j
public class StorageFactory {

    private static final String storageTypeKey="magic4j.storage.type";
    private static final String storageEnabledDbKey="magic4j.storage.enabledDb";

    private static String getYmlProperty(String key){
        String propertyName = "application.yml";
        Resource resource = new ClassPathResource(propertyName);
        Properties properties;
        try {
            YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
            yamlFactory.setResources(resource);
            properties =  yamlFactory.getObject();
            if(properties!=null){
                return properties.getProperty(key,"");
            }else {
                return null;
            }
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            return null;
        }

    }

    public static StorageService build(StorageTypeEnum storageType) {
        StorageService storageService = null;
        if (StorageTypeEnum.ALIYUN_OSS.getType() == storageType.getType()) {
            storageService = SpringContextUtils.getBean(AliyunOssStorageServiceImpl.class);
        } else if (StorageTypeEnum.TENCENT_COS.getType() == storageType.getType()) {
            storageService = SpringContextUtils.getBean(TencentCosStorageServiceImpl.class);
        } else if (StorageTypeEnum.QINIU_KODO.getType() == storageType.getType()) {
            storageService = SpringContextUtils.getBean(QiniuKodoStorageServiceImpl.class);
        } else if (StorageTypeEnum.FASTDFS.getType() == storageType.getType()) {
            storageService = SpringContextUtils.getBean(FastdfsStorageServiceImpl.class);
        } else if (StorageTypeEnum.SFTP.getType() == storageType.getType()) {
            storageService = SpringContextUtils.getBean(SftpStorageServiceImpl.class);
        } else if (StorageTypeEnum.LOCAL.getType() == storageType.getType()) {
            storageService = SpringContextUtils.getBean(LocalStorageServiceImpl.class);
        } else if (StorageTypeEnum.MINIO.getType() == storageType.getType()) {
            storageService = SpringContextUtils.getBean(MinioStorageServiceImpl.class);
        }
        if (storageService == null) {
            //默认实现
            storageService = SpringContextUtils.getBean(LocalStorageServiceImpl.class);
        }
        return storageService;
    }

    public static StorageService build(){
        String storageType = "";
        String enabledDb = getYmlProperty(storageEnabledDbKey);
        if(StrUtil.isNotBlank(enabledDb)) {
            if(Boolean.parseBoolean(enabledDb)){
                CacheService cacheService = SpringContextUtils.getBean(CacheService.class);
                //获取文件存储方式
                storageType = cacheService.get(Constants.STORAGE_TYPE, () -> {
                    // 通过DB获取默认存储方式
                    DataSource dataSource = SpringContextUtils.getBean(DataSource.class);
                    try {
                        return Db.use(dataSource).queryString("SELECT config_value FROM sys_config WHERE config_key=? AND status=0 AND delete_flag=0", Constants.SYS_CONFIG_KEY.FILE_STORAGE_TYPE);
                    } catch (Exception e) {
                        return null;
                    }
                });
            }else {
                //读取配置的文件上传存储方式
                storageType = getYmlProperty(storageTypeKey);
            }
        }else {
            //读取配置的文件上传存储方式
            storageType = getYmlProperty(storageTypeKey);
        }
        return build(storageType);
    }

    public static StorageService build(String storageType){
        StorageService storageService = null;
        if(StrUtil.isNotBlank(storageType)) {
            if (StorageTypeEnum.ALIYUN_OSS.getDescription().equalsIgnoreCase(storageType)) {
                storageService = SpringContextUtils.getBean(AliyunOssStorageServiceImpl.class);
            } else if (StorageTypeEnum.TENCENT_COS.getDescription().equalsIgnoreCase(storageType)) {
                storageService = SpringContextUtils.getBean(TencentCosStorageServiceImpl.class);
            } else if (StorageTypeEnum.QINIU_KODO.getDescription().equalsIgnoreCase(storageType)) {
                storageService = SpringContextUtils.getBean(QiniuKodoStorageServiceImpl.class);
            } else if (StorageTypeEnum.FASTDFS.getDescription().equalsIgnoreCase(storageType)) {
                storageService = SpringContextUtils.getBean(FastdfsStorageServiceImpl.class);
            } else if (StorageTypeEnum.SFTP.getDescription().equalsIgnoreCase(storageType)) {
                storageService = SpringContextUtils.getBean(SftpStorageServiceImpl.class);
            } else if (StorageTypeEnum.LOCAL.getDescription().equalsIgnoreCase(storageType)) {
                storageService = SpringContextUtils.getBean(LocalStorageServiceImpl.class);
            } else if (StorageTypeEnum.MINIO.getDescription().equalsIgnoreCase(storageType)) {
                storageService = SpringContextUtils.getBean(MinioStorageServiceImpl.class);
            }
        }
        if (storageService == null) {
            //默认实现
            storageService = SpringContextUtils.getBean(LocalStorageServiceImpl.class);
        }
        return storageService;
    }
}
